Примитивны синхронизации, потокобезопасные коллекции

⚙ lock → Monitor

lock если объект монитора уже закрыт просто блокирует поток

lock(obj){
	...
}

Эта конструкция превращается в правую конструкцию

try{
	var lockTaken = false;
	Monitor.Enter(obj, ref lockTaken);
	...
}
finally
{
	if(lockTaken)
	{
		Monitor.Exit(obj)
	}
}

⚙ MethodImplOptions.Synchronized

[MethodImpl(MethodImplOptions.Synchronized)]
public void CriticalMethod()
{
	...
}
  • внутри lock нельзя использовать ключевое слово await, код не скомпилируется, но можно самому развернуть в Monitor и все будет норм, но теперь эксепшн. Проблема в том, что код после await может быть продолжен не тем потоком, который его начал. Тогда lock будет сниматься не тем потоком который его установил, что не правильно
  • Объектом синхронизации должен быть ссылочный тип из-за того что во время упаковки происходит создание нового объекта
  • лок может быть вложеным с одним и тем же типом блокировки, так как блокировка это инт, её можно накладывать несколько раз

⚙ SpinLock

Он требуется чтобы пореже переключать контекст, т.к. в случае обычного лока, контекст переключается постоянно

private SpinLock obj = new SpinLock();

public void Method(){
	var lockTaken = false;
	try
	{
		obj.Enter(ref lockTaken);
	}
	finally
	{
		if(lockTaken){
			obj.Exit(false);
		}
	}
}

Эта штука не перключает сразу контекст а запускает в цикле метод SpinOnce, в нем есть три варинта

SpinLock это структура, поэтому его нужно передавать строко по ref, иначе он будет не иметь смысла

Untitled 2.png

⚙ ReaderWriderLockSlim

Untitled 1.png

Данная штука позволяет область кода сделать такой, чтобы все кто хотели могли читать, но писать мог только один и при этом, если кто то начинает писать, то все ребята на чтение заканчивают читать а все попытке прочесть становятся в очередь пока не закончиться запись

⚙ SemaphoreSlim

  • Пример использования, допустим хотим распаралелить число запросов куда-то, но не хотим чтобы их было слишком много

Существуют примитивы с приставкой Slim и без, отличие в том, что без ткого суффикса примитивы появились раньше, когда дотнет был только под винду и они отличаются тем что опускали примитивы на уровень ОС, в то время как Slim разбираются на уровне приложения

Есть два вида потоко безопасных коллекций:

  1. Cuncurent регулируют потоки на добавление и удаление
  2. Immutable регулируют потоки тем, что на каждое действие создают новый список
  • CuncurrentBag

Добавляя новый элемент, поток добавляет каждый в свою коллекцию, а если читать, то сначала из своего, а потом блокировать другой поток и читать из чужого